/*
 * File Name:               UIDragButton_FixedHold.cs
 * 
 * Description:             普通类
 * Author:                  lisiyu <576603306@qq.com>

 * Create Date:             2017/06/07
 */

namespace UnityEngine.UI
{
    using UnityEngine;
    using EventSystems;
    using System;

    [AddComponentMenu("UI/DragButton - 2个事件 - 固定按住")]
    [DisallowMultipleComponent]
    [RequireComponent(typeof(Image))]
    public class UIDragButton_FixedHold : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
    {
        public Action<ModeType> onClick;

        public Graphic[] Image_Centers;
        public Graphic[] Image_Ups;
        public RectTransform Trans_Area;               // 移动节点与固定节点的最大距离区域表示 横向宽度为向上 高度为向下

        private float mMaxDistance_UP = 15f;             // 移动节点与固定节点的最大距离
        private float mMaxDistance_DOWN = 25f;           // 移动节点与固定节点的最大距离

        private Vector3 mInitPos;

        private bool mNeedCheck;                    // 是否需要检测
        void Awake()
        {
            Vector3[] tmpAreaRect = new Vector3[4];
            Trans_Area.GetWorldCorners(tmpAreaRect);
            mMaxDistance_UP = tmpAreaRect[2].x - tmpAreaRect[0].x;
            mMaxDistance_DOWN = tmpAreaRect[1].y - tmpAreaRect[0].y;

            mInitPos = transform.position;

            mModeType = ModeType.None;
            display(mModeType);
        }

        public void OnDrag(PointerEventData eventData)
        {
            if (!mNeedCheck) return;
            setMovedPos_ByScreen(eventData.position);
        }

        public void OnPointerDown(PointerEventData eventData)
        {
            mNeedCheck = true;

            mInitPos = UIManager.Singleton.ScreenToWorldPoint(eventData.position, transform.position.z);
            setMovedPos_ByScreen(eventData.position);
        }

        public void OnPointerUp(PointerEventData eventData)
        {
            mNeedCheck = false;
            setModeType(ModeType.None);
        }

        public enum ModeType
        {
            None,
            Center,
            Up,
        }

        private ModeType mModeType;
        private void setMovedPos_ByScreen(Vector2 screenPos)
        {
            var retPos = UIManager.Singleton.ScreenToWorldPoint(screenPos, transform.position.z);

            var maxDis = retPos.y >= mInitPos.y ? mMaxDistance_UP : mMaxDistance_DOWN;

            var dir = (retPos - mInitPos);
            var dis = dir.magnitude;

            if(dis > maxDis * 1.5f)
            {
                mNeedCheck = false;
                setModeType(ModeType.None);
            }
            else if (dis > maxDis / 2)
            {
                setModeType(ModeType.Up);
            }
            else
            {
                setModeType(ModeType.Center);
            }
        }

        private void OnDisable()
        {
            mNeedCheck = false;
            setModeType(ModeType.None);
        }

        private readonly float COLOR_SHOW = 1;
        private readonly float COLOR_HIDE = 0;
        private readonly float COLOR_ALPHA = 0.5f;
        private void display(ModeType modeType)
        {
            for (int i = 0; i < Image_Centers.Length; i++)
            {
                var tmpColor = Image_Centers[i].color;
                tmpColor.a = (modeType == ModeType.Center || modeType == ModeType.None) ? COLOR_SHOW : COLOR_ALPHA;
                Image_Centers[i].color = tmpColor;
            }

            for (int i = 0; i < Image_Ups.Length; i++)
            {
                var tmpColor = Image_Ups[i].color;
                tmpColor.a = (modeType == ModeType.Center || modeType == ModeType.None) ? COLOR_HIDE : COLOR_SHOW;
                Image_Ups[i].color = tmpColor;
            }
        }

        private void setModeType(ModeType modeType)
        {
            if (mModeType == modeType)
                return;

            mModeType = modeType;
            display(mModeType);
            if (onClick != null)
                onClick(mModeType);
        }
    }
}